package cn.linkstudy.controller;

import cn.linkstudy.common.Result;
import cn.linkstudy.entity.AiQuestion;
import cn.linkstudy.entity.ChatRecord;
import cn.linkstudy.service.AiService;
import cn.linkstudy.service.ChatRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

/**
 * AI相关接口控制器
 * 提供AI出题、AI对话等REST API
 */
@RestController
@RequestMapping("/chat")
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
public class AiController {

    @Autowired
    private AiService aiService;

    @Autowired
    private ChatRecordService chatRecordService;

    /**
     * AI出题接口
     * 
     * @param request 包含userId、subject、grade、difficulty
     * @return 题目信息
     */
    @PostMapping("/generate-question")
    public Result<Map<String, Object>> generateQuestion(@RequestBody Map<String, Object> request) {
        try {
            Long userId = Long.valueOf(request.get("userId").toString());
            String subject = (String) request.get("subject");
            String grade = (String) request.get("grade");
            String difficulty = (String) request.get("difficulty");

            if (userId == null || subject == null || grade == null || difficulty == null) {
                return Result.error("参数不完整");
            }

            Map<String, Object> result = aiService.generateQuestion(userId, subject, grade, difficulty);

            if ((Boolean) result.get("success")) {
                return Result.success("生成题目成功", result);
            } else {
                return Result.error((String) result.get("message"));
            }
        } catch (Exception e) {
            return Result.error("生成题目失败：" + e.getMessage());
        }
    }

    /**
     * AI对话接口
     * 
     * @param userId    用户ID
     * @param sessionId 会话ID
     * @param message   用户消息
     * @return AI回复
     */
    @PostMapping("/save")
    public Result<String> save(@RequestBody Map<String, Object> request) {
        try {
            Long userId = Long.valueOf(request.get("userId").toString());
            String sessionId = (String) request.get("sessionId");
            String message = (String) request.get("message");

            if (userId == null || sessionId == null || message == null) {
                return Result.error("参数不完整");
            }

            String response = aiService.chat(userId, sessionId, message);
            return Result.success("对话成功", response);
        } catch (Exception e) {
            return Result.error("对话失败：" + e.getMessage());
        }
    }

    /**
     * AI流式对话输出
     */
    @PostMapping("/chat-stream")
    public void chatStream(@RequestBody Map<String, Object> request, HttpServletResponse response) {
        response.setContentType("text/plain;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        try {
            Long userId = Long.valueOf(request.get("userId").toString());
            String sessionId = request.get("sessionId").toString();
            String message = request.get("message").toString();
            PrintWriter writer = response.getWriter();
            // 假设aiService.chat返回完整回复，这里模拟分块输出
            String aiReply = aiService.chat(userId, sessionId, message);
            // 简单分块输出（每20字一块）
            int chunkSize = 20;
            for (int i = 0; i < aiReply.length(); i += chunkSize) {
                String chunk = aiReply.substring(i, Math.min(i + chunkSize, aiReply.length()));
                writer.write(chunk);
                writer.flush();
                Thread.sleep(80); // 模拟流式延迟
            }
            writer.close();
        } catch (Exception e) {
            // 异常时输出错误信息
            try {
                PrintWriter writer = response.getWriter();
                writer.write("[ERROR] " + e.getMessage());
                writer.close();
            } catch (Exception ignored) {
            }
        }
    }

    /**
     * 获取用户的出题历史
     */
    @GetMapping("/questions")
    public Result<List<AiQuestion>> getUserQuestions(@RequestParam Long userId) {
        try {
            List<AiQuestion> questions = aiService.getUserQuestions(userId);
            return Result.success("获取成功", questions);
        } catch (Exception e) {
            return Result.error("获取出题历史失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户的对话历史（会话列表）
     */
    @GetMapping("/sessions")
    public Result<List<ChatRecord>> getSessions(@RequestParam Long userId) {
        try {
            List<ChatRecord> chats = chatRecordService.getUserChats(userId, null);
            return Result.success("获取成功", chats);
        } catch (Exception e) {
            return Result.error("获取对话历史失败：" + e.getMessage());
        }
    }

    /**
     * 获取单个会话历史
     */
    @GetMapping("/history")
    public Result<ChatRecord> getHistory(@RequestParam Long userId, @RequestParam String sessionId) {
        try {
            ChatRecord chat = chatRecordService.getHistory(userId, sessionId);
            return Result.success("获取成功", chat);
        } catch (Exception e) {
            return Result.error("获取会话历史失败：" + e.getMessage());
        }
    }

    /**
     * AI引导式出题（多轮消息）
     */
    @PostMapping("/guide-chat")
    public Result<String> guideChat(@RequestBody Map<String, Object> request) {
        try {
            // 获取messages参数
            @SuppressWarnings("unchecked")
            List<Map<String, String>> messages = (List<Map<String, String>>) request.get("messages");
            if (messages == null) {
                return Result.error("参数messages不能为空");
            }

            // 数学选择题专用system prompt
            String systemPrompt = "你是一个专为中小学生设计的数学AI导学助手🤖。你的任务是引导学生进行数学选择题练习，始终保持友好、耐心和鼓励的语气。\n\n【核心规则 - 极其重要】：\n当需要用户做出选择时，你必须使用 [Button: \"按钮文字\"] 的格式来包裹每一个选项。程序会识别这个格式并将其转换为可点击的按钮。绝对禁止以纯文本列表的形式展示选项。\n\n【数学选择题完整交互流程】：\n\n**第一步：问候与年级选择**\n- 主动问候用户，表达欢迎\n- 提供年级选项让用户选择\n- 格式：[Button: \"小学\"] [Button: \"初中\"] [Button: \"高中\"]\n- 示例：你好！我是你的数学学习伙伴😊 为了给你推荐合适的数学题目，请先选择你的年级：[Button: \"小学\"] [Button: \"初中\"] [Button: \"高中\"]\n\n**第二步：知识点选择**\n- 对用户的年级选择表示欢迎\n- 根据年级提供对应的数学知识点选择\n- 小学：[Button: \"数与运算\"] [Button: \"几何基础\"] [Button: \"应用问题\"]\n- 初中：[Button: \"代数与方程\"] [Button: \"几何进阶\"] [Button: \"概率与统计\"]\n- 高中：[Button: \"函数与微积分\"] [Button: \"立体几何与解析几何\"] [Button: \"概率统计与逻辑\"]\n- 同时提示：你也可以输入其他知识点，比如\"分数加减法\"、\"一元二次方程\"等\n\n**第三步：出题与选项**\n- 根据用户的年级和知识点生成一道合适的数学选择题\n- 每个选项都必须用 [Button: \"...\"] 包裹\n- 格式：\n题目：[题目内容]\n[Button: \"A. 选项内容\"] [Button: \"B. 选项内容\"] [Button: \"C. 选项内容\"] [Button: \"D. 选项内容\"]\n\n**第四步：反馈与后续操作**\n- 判断用户答案的对错\n- 给出鼓励性反馈和详细解析\n- 提供下一步操作选项：[Button: \"继续下一题\"] [Button: \"换个知识点\"] [Button: \"换个年级\"] [Button: \"结束答题\"]\n\n【语言风格】：\n- 使用友好、鼓励的语气\n- 多使用表情符号：😊✨📝🎯💪👍🌟🎉等\n- 答对时表扬：\"太棒了！👍\"、\"答对了！🎉\"\n- 答错时鼓励：\"没关系，继续加油！💪\"、\"很好的尝试！😊\"\n\n【绝对禁止】：\n- 不要使用纯文本列表格式（如 A. XXX, B. XXX）\n- 不要在同一轮中提供多种类型的选择\n- 不要忘记使用 [Button: \"...\"] 格式包裹选项\n\n【结束答题严格要求】：\n- 当用户点击“结束答题”按钮或表达结束意图时，你必须严格按照如下流程输出：\n  1. 先统计本次答题情况（总题数、答对题数、答错题数、正确率）；\n  2. 再分析强项和薄弱点；\n  3. 再给出具体学习建议。\n- 禁止输出任何操作按钮或“继续答题”等提示。\n- 输出内容要简明清晰，适合学生和家长理解。\n- 必须严格按照顺序输出，缺一不可。\n\n【格式要求】：\n- 用清晰的分段和换行展示内容，每一部分（统计、分析、建议）用表情符号和标题分隔。\n- 统计部分用“📊 本次答题总结”，分析部分用“🌟 表现分析”，建议部分用“📚 学习建议”开头。\n- 每个要点单独成行，便于学生和家长一眼看懂。\n- 结尾用鼓励语和表情符号收尾。\n- 严禁输出一大段无分段的内容。";

            // 若首条不是system，则插入
            if (messages.isEmpty() || !"system".equals(messages.get(0).get("role"))) {
                messages.add(0, Map.of("role", "system", "content", systemPrompt));
            }

            // 如果仅有system prompt或用户未输入任何内容，直接返回带按钮的初始欢迎语
            if (messages.size() == 1) {
                String welcome = "你好！我是你的数学学习伙伴😊 很高兴陪你一起探索数学的奥秘！为了给你推荐适合的数学题目，请先选择你的年级：[Button: \"小学\"] [Button: \"初中\"] [Button: \"高中\"]";
                return Result.success(welcome);
            }

            // 调用AI
            String aiReply = aiService.guideChatWithMessages(messages);
            return Result.success(aiReply);
        } catch (Exception e) {
            return Result.error("AI引导出题失败：" + e.getMessage());
        }
    }

    /**
     * AI答题总结分析
     */
    @PostMapping("/summary")
    public Result<String> summary(@RequestBody Map<String, Object> request) {
        try {
            Object quizData = request.get("quizData");
            if (quizData == null) {
                return Result.error("参数quizData不能为空");
            }
            // 完整交互流程的总结请求prompt
            String summaryPrompt = "你是一个智慧学习助手。现在用户已经完成了一轮数学答题，请你严格按照以下流程和要求，生成总结分析：\n" +
                    "\n【交互流程】\n" +
                    "1. 首先，统计本次答题的情况，包括：\n" +
                    "   - 总题数\n" +
                    "   - 答对题数\n" +
                    "   - 答错题数\n" +
                    "   - 正确率（百分比，保留整数）\n" +
                    "   请用清晰的列表或分段方式展示这些数据。\n" +
                    "2. 然后，根据用户的答题表现，分析其强项和薄弱点，指出在哪些知识点或题型上表现较好，哪些方面需要加强。\n" +
                    "3. 最后，给出具体的学习建议，如建议多练习哪些知识点、如何改进学习方法等。语言要积极鼓励，适合中小学生，可适当用表情符号。\n" +
                    "\n【特别要求】\n" +
                    "- 必须严格按照上述顺序输出内容，先统计，再分析，再建议，不能只给鼓励语。\n" +
                    "- 禁止出现任何‘选项按钮’‘继续答题’‘重新开始练习’等操作提示，只输出统计、分析和建议。\n" +
                    "- 输出内容要简明清晰，便于学生和家长一眼看懂。\n" +
                    "\n【输出格式示例】：\n---\n本次答题情况：\n- 总题数：5\n- 答对题数：3\n- 答错题数：2\n- 正确率：60%\n\n分析与建议：\n你在‘分数加减法’题型表现优秀，但‘几何’题型有待加强。建议多练习几何相关题目，继续保持积极的学习态度！🌟\n---\n\n请严格按照上述流程和格式输出内容。\n\n【格式要求】：\n- 用清晰的分段和换行展示内容，每一部分（统计、分析、建议）用表情符号和标题分隔。\n- 统计部分用“📊 本次答题总结”，分析部分用“🌟 表现分析”，建议部分用“📚 学习建议”开头。\n- 每个要点单独成行，便于学生和家长一眼看懂。\n- 结尾用鼓励语和表情符号收尾。\n- 严禁输出一大段无分段的内容。";
            java.util.List<java.util.Map<String, String>> messages = java.util.List.of(
                    java.util.Map.of("role", "system", "content", summaryPrompt),
                    java.util.Map.of("role", "user", "content", "请为我的答题情况做一个总结分析：" + quizData.toString()));
            String aiReply = aiService.guideChatWithMessages(messages);
            return Result.success(aiReply);
        } catch (Exception e) {
            return Result.error("生成总结失败：" + e.getMessage());
        }
    }
}